package com.ruoyi.service.impl;

import com.ruoyi.entity.dto.ChatRequest;
import com.ruoyi.entity.dto.ChatResponse;
import com.ruoyi.entity.dto.KnowledgeBase;
import com.ruoyi.service.LlmService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.http.client.MultipartBodyBuilder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
public class LlmServiceImpl implements LlmService {

    @Value("${anythingllm.base-url}")
    private String baseUrl;

    @Value("${anythingllm.api-key}")
    private String apiKey;

    /**
     * 发送 POST 请求到 AnythingLLM 的 API
     */
    private final WebClient webClient = WebClient.create();


    /**
     * AnythingLLM 中创建一个新的知识库时调用此方法
     * @param knowledgeBase 知识库的名称（name）和描述（description）的对象
     * @return
     */
    @Override
    public String createKnowledgeBase(KnowledgeBase knowledgeBase) {
        Map<String, String> body = new HashMap<>();
        body.put("name", knowledgeBase.getName());
        body.put("description", knowledgeBase.getDescription());

        return webClient.post()
                .uri(baseUrl + "/v1/workspace/new")
                .header("Authorization", "Bearer " + apiKey)
                .bodyValue(body)
                .retrieve()
                .bodyToMono(String.class)
                .block();
    }

    /**
     * 将文件上传到指定的知识库中
     * @param file   需要上传的文件，类型为 MultipartFile
     * @param workspaceSlug  目标知识库的 ID
     * @return
     */
    @Override
    public String uploadDocument(MultipartFile file, String workspaceSlug) {
        MultipartBodyBuilder builder = new MultipartBodyBuilder();
        builder.part("file", file.getResource())
                .filename(file.getOriginalFilename());

        return webClient.post()
                .uri(baseUrl + "/v1/workspace/" + workspaceSlug + "/update-embeddings") // 修正路径
                .header("Authorization", "Bearer " + apiKey)
                .contentType(MediaType.MULTIPART_FORM_DATA)
                .body(BodyInserters.fromMultipartData(builder.build()))
                .retrieve()
                .bodyToMono(String.class)
                .block();
    }

    /**
     * 向指定的知识库发送问题，并获取 AnythingLLM 的回复
     * @param request 包含用户问题（question）和目标知识库 ID（knowledgeBaseId）的对象
     * @return
     */
    @Override
    public ChatResponse chat(ChatRequest request) {
        try {
            Map<String, Object> requestBody = new HashMap<>();
            requestBody.put("message", request.getQuestion());

            return webClient.post()
                    .uri(baseUrl + "/v1/workspace/" + request.getWorkspaceSlug() + "/chat")
                    .header("Authorization", "Bearer " + apiKey)
                    .bodyValue(requestBody)
                    .retrieve()
                    .onStatus(status -> !status.is2xxSuccessful(),
                            response -> response.bodyToMono(String.class).flatMap(body -> {
                                log.error("LLM API错误: 状态码 {}，响应: {}", response.statusCode(), body);
                                return Mono.error(new RuntimeException(body));
                            }))
                    .bodyToMono(ChatResponse.class)
                    .block();
        } catch (Exception e) {
            log.error("LLM调用失败: {}", e.getMessage());
            return new ChatResponse("服务暂时不可用: " + e.getMessage(), Collections.emptyList());
        }
    }
}
